/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "面.h"



#include "intern/网格变换/顶点矩阵变换.h"
#include "intern/网格.h"

#include <文件/file_载入保存数据.h>
#include <几何图形/图形相交.h>
#include <B_几何图形/三角形.h>
#include <matXX.h>



//S_Mesh板载缓存* f_构建网格板载内存(S_设备环境& ctx) {
//	S_Mesh板载缓存* me = 0;
//	
//	me->m_顶点 = f_buf_create板载缓存(ctx, sizeof(vec3));
//	me->m_法线 = f_buf_create板载缓存(ctx, sizeof(vec3));
//	me->m_颜色 = f_buf_create板载缓存(ctx, sizeof(vec4));
//	me->m_索引 = f_buf_create板载缓存(ctx, sizeof(uint32));
//	//me->m_权重 = f_create板载缓存(ctx, sizeof(float32));
//	me->m_间接 = f_buf_create板载缓存(ctx, sizeof(float32));
//
//	me->m_UV1 = f_buf_create板载缓存(ctx, sizeof(vec2));
//	me->m_UV索引 = f_buf_create板载缓存(ctx, sizeof(vec2));
//
//	return me;
//}



void f_fillVKMesh(S_VKMesh板载缓存* buf) {
	//buf->m_顶点 = f_create板载缓存(ctx, sizeof(vec3));
}





void f_surface_初始化GPU内存(S_设备环境& ctx) {
	uint32 Flags = E_板载缓存类型::e_SSBO | E_板载缓存类型::e_光追BVH | E_板载缓存类型::e_着色端内存地址;
	S_Mesh::g_顶点v = f_buf_create板载缓存(ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO | Flags, sizeof(vec3), 0);
	S_Mesh::g_顶点vn = f_buf_create板载缓存(ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO | Flags, sizeof(S_VN), 0);
	S_Mesh::g_顶点vc = f_buf_create板载缓存(ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO | Flags, sizeof(S_VC), 0);
	S_Mesh::g_顶点vnt = f_buf_create板载缓存(ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO | Flags, sizeof(S_VNT1), 0);
	S_Mesh::g_索引 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_INDEX, E_板载缓存类型::e_INDEX | Flags, sizeof(uint32), 0);
	S_Mesh::g_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_FaceElement), 0);

	S_Mesh::g_BLAS = f_buf_create板载缓存(ctx, 1, E_板载缓存类型::e_光追底层加速结构, 1);
	S_Mesh::g_TLAS = f_buf_create板载缓存(ctx, 1, E_板载缓存类型::e_光追顶层加速结构, 1);
	S_Mesh::g_实例AS = f_buf_create板载缓存(ctx, sizeof(VkAccelerationStructureInstanceKHR), E_板载缓存类型::e_光追实例, 1);
	S_Mesh::g_RtMesh = f_buf_create板载缓存(ctx, sizeof(S_ObMesh), E_板载缓存类型::e_SSBO, 0);

	S_Mesh::g_骨骼属性 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uvec2), 1);
	S_Mesh::g_骨骼权重 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_BonesWeigth), 1);
	//S_Mesh::g_骨骼矩阵 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uvec2), 0);
	

	S_Mesh::g_间接 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_INDIRECT, sizeof(S_VkDrawIndirectCommand));
	S_Mesh::g_索引间接 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_INDIRECT, sizeof(S_VkDrawIndexedIndirectCommand));
	S_Mesh::g_网格属性 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, sizeof(S_MeshTranformProp));
}

void f_surface_释放所有GPU内存() {
	f_buf_release板载缓存(S_Mesh::g_顶点v);
	f_buf_release板载缓存(S_Mesh::g_顶点vn);
	f_buf_release板载缓存(S_Mesh::g_顶点vc);
	f_buf_release板载缓存(S_Mesh::g_顶点vnt);

	f_buf_release板载缓存(S_Mesh::g_BLAS);
	f_buf_release板载缓存(S_Mesh::g_TLAS);
	f_buf_release板载缓存(S_Mesh::g_实例AS);
	f_buf_release板载缓存(S_Mesh::g_RtMesh);

	f_buf_release板载缓存(S_Mesh::g_骨骼属性);
	f_buf_release板载缓存(S_Mesh::g_骨骼权重);

	f_buf_release板载缓存(S_Mesh::g_间接);
	f_buf_release板载缓存(S_Mesh::g_索引间接);
}



S_Mesh* f_surface_创建网格对象(const S_Mesh* fromesh, S_设备环境& ctx, E_网格数据枚举 type) {
	S_Mesh* me = 0;

	switch (type) {
	case e_Mesh_CPU:
		me = new S_Mesh_CPU();
		break;
	case e_Mesh_CUDA: {
			me = new S_Mesh_CUDA();
			if (fromesh) {
				me->f_AddMesh(*fromesh);
			}
		}
		break;
	case e_Mesh_VULKAN: {
			S_VKMesh板载缓存* buf = new S_VKMesh板载缓存(ctx);
			me = buf;
		}
		
		break;
	default:
		break;
	}

	return me;
}

S_Mesh* f_surface_创建网格对象(E_网格数据枚举 type) {
	S_Mesh* me = 0;

	switch (type)
	{
	case e_Mesh_CPU:
		me = new S_Mesh_CPU();
		break;
	case e_Mesh_CUDA: {
		me = new S_Mesh_CUDA();
		break;
	}			
	case e_Mesh_VULKAN: {
		S_VKMesh板载缓存* buf = new S_VKMesh板载缓存();
		me = buf;
		break;
	}		  
	default:
		break;
	}

	return me;
}

S_Mesh* f_surface_创建网格对象(S_设备环境& ctx, E_网格数据枚举 type) {
	S_Mesh* me = 0;

	switch (type)
	{
	case e_Mesh_CPU:
		me = new S_Mesh_CPU();
		break;
	case e_Mesh_CUDA: {
		me = new S_Mesh_CUDA();
		break;
	}
	case e_Mesh_VULKAN: {
		S_VKMesh板载缓存* buf = new S_VKMesh板载缓存(ctx);
		me = buf;
		break;
	}
	default:
		return f_surface_创建网格对象();
		break;
	}

	return me;
}

void f_surface_释放网格(S_Mesh* mesh) {
	delete mesh;
}

S_Mesh* f_surface_创建实例(S_Mesh* 源, bool 关联颜色) {
	S_VKMesh板载缓存* me = dynamic_cast<S_VKMesh板载缓存*>(源);
	if (me) {
		S_Mesh* mesh = new S_VKMesh板载缓存(me);

		if (关联颜色) {
			mesh->m_颜色 = me->m_颜色;
		}
		else {
			f_mesh_创建颜色缓存(mesh, me->m_Ctx);
		}

		if (源->m_绘制属性) {

		}
		return mesh;
	}
	return nullptr;
}

void f_surface_关联实例(S_Mesh* mesh, const S_Mesh* 源) {
	S_VKMesh板载缓存* me = dynamic_cast<S_VKMesh板载缓存*>(mesh);
	me->f_拷贝实例(源);
}

void f_surface_Copy(S_Mesh* mesh, S_Mesh* 源) {
	f_mesh_顶点类型切换(mesh, 源);
	
	f_buf_copy(*mesh->m_顶点,   *源->m_顶点);
	f_buf_copy(*mesh->m_UV,     *源->m_UV);
	f_buf_copy(*mesh->m_UV索引, *源->m_UV索引);
	f_buf_copy(*mesh->m_索引,   *源->m_索引);
	f_buf_copy(*mesh->m_面,     *源->m_面);
	
	f_buf_copy(mesh->m_网格元素属性, 源->m_网格元素属性);


	if (源->m_间接) f_buf_copy(*mesh->m_间接, *源->m_间接);
	if (源->m_绘制属性) {
		f_mesh_set绘制属性(mesh, *源->m_绘制属性);
	}

	mesh->m_Material = 源->m_Material;
	if (mesh->m_Material) {
		//mesh->m_Material->mf_GPU材质槽更新(mesh->m_Material, mesh->m_GPU参数布局, 2);
	}

	f_surface_计算包围盒(mesh);
	//mesh->m_Bound = 源->m_Bound;
}







S_2D画布* f_surface_创建2D画布(const S_2D画布* fromesh, S_设备环境& ctx) {
	switch (ctx.m_Type) {
	case E_绘图API::E_Vulkan:
		{
			S_2D画布* buf = new S_2D画布(ctx);
			return buf;
		}
		break;
	default:
		break;
	}
	return nullptr;
}

void f_surface_释放2D画布(S_2D画布* fromesh) {
	delete fromesh;
}

void f_surface_重置顶点数量(S_Mesh* mesh, uint64 num) {
	
}

void f_surface_fill顶点数据(S_Mesh* mesh, const std::vector<vec3>& data, uint32 vertFlags) {
	*mesh->m_顶点配置Flags = vertFlags;
	mesh->f_fill顶点(data.data(), data.size());
}

void f_填充颜色数据(S_Mesh* mesh, const std::vector<S_RGBA8UI>& col) {
	mesh->f_fill颜色(col);
}

//void f_填充法线数据(S_Mesh* mesh, const std::vector<vec3>& data) {
	//f_fill板载缓存(mesh->m_板载缓存->m_法线, data, E_板载缓存类型::e_VBO);
//}

void f_填充索引数据(S_Mesh* mesh, const std::vector<uint32>& data) {
	f_surface_fill索引数据(mesh, data);
}

void f_surface_fill顶点颜色(S_Mesh* me, const S_RGBA8UI& data) {
	//auto 顶点 = mesh->f_map顶点();
	//uint32 num = 顶点.count;
	uint32 num = me->m_顶点->m_Mem.m_大小;
	uint32 color = f_PackData4X8(data);
	if (*me->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vc = (S_VC*)顶点.point;
		S_VC* vc = f_buf_VC_ptr(*me->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vc[i].color = color;
		}
	}
	//mesh->f_unmap顶点();
}

void f_surface_fill顶点颜色(S_Mesh* me, const std::vector<S_RGBA8UI>& data, uint32 offset) {
	//auto 顶点 = mesh->f_map顶点();

	uint32 num = data.size();
	if (*me->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vc = (S_VC*)顶点.point;
		S_VC* vc = f_buf_VC_ptr(*me->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vc[i + offset].color = f_PackData4X8(data[i]);
		}
	}

	//mesh->f_unmap顶点();
}

void f_surface_fill顶点颜色(S_Mesh* me, const S_RGBA8UI& data, uint32 offset, uint32 num) {
	//auto 顶点 = mesh->f_map顶点();
	uint32 color = f_PackData4X8(data);
	if (*me->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vc = (S_VC*)顶点.point;
		S_VC* vc = f_buf_VC_ptr(*me->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vc[i + offset].color = color;
		}
	}
	//mesh->f_unmap顶点();
}



void f_surface_get网格顶点数据(S_Mesh* me, const S_UI32Array* index, S_Vec3Array* data, int32 成员) {
	if (!me || !index) {
		return;
	}

	uint32 数量限制 = me->m_顶点->m_Mem.m_大小;
	uint32 num = index->count;
	const uint32* 索引 = index->ptr_userData;

	f_core_array_resize((S_Array*)data, num);
	if(!数量限制) return;

	switch (*me->m_顶点配置Flags) {
		case E_顶点组合标志::e_坐标_法线_UV: {
			S_VNT1* VNT = f_buf_VNT_ptr(*me->m_顶点);
			for (uint32 i = 0; i < num; ++i) {
				uint32 当前索引 = 索引[i];
				if (当前索引 >= 数量限制) {
					当前索引 = 数量限制-1;
				}
				switch (成员) {
					case 0: data->ptr_userData[i] = VNT[当前索引].vert;   break;
					case 1: data->ptr_userData[i] = VNT[当前索引].normal; break;
				}
			}
			break;
		}
		case E_顶点组合标志::e_坐标_法线_UV_颜色: {
			break;
		}
		case E_顶点组合标志::e_坐标: {
			break;
		}
		case E_顶点组合标志::e_坐标_UV: {
			break;
		}
		case E_顶点组合标志::e_坐标_权重: {
			break;
		}
		case E_顶点组合标志::e_坐标_法线: {
			S_VN* xyz = f_buf_VN_ptr(*me->m_顶点);
			break;
		}
		case E_顶点组合标志::e_坐标_颜色: {
			break;
		}
	}
}

void f_surface_set网格顶点数据(S_Mesh* me, const S_UI32Array* index, const S_Vec3Array* data, int32 成员) {
	if(!me || !index) {
		return;
	}

	uint32 数量限制 = me->m_顶点->m_Mem.m_大小 - 1;
	uint32 num = DEF_Min(index->count, data->count);
	const uint32* 索引 = index->ptr_userData;

	switch (*me->m_顶点配置Flags) {
		case E_顶点组合标志::e_坐标_法线_UV: {
			S_VNT1* VNT = f_buf_VNT_ptr(*me->m_顶点);
			for (uint32 i = 0; i < num; ++i) {
				uint32 当前索引 = 索引[i];
				if (当前索引 > 数量限制) {
					当前索引 = 数量限制;
				}

				switch (成员) {
					case 0: VNT[当前索引].vert = data->ptr_userData[i];   break;
					case 1: VNT[当前索引].normal = data->ptr_userData[i]; break;
				}
			}
			break;
		}
		case E_顶点组合标志::e_坐标_法线_UV_颜色: {
			break;
		}
		case E_顶点组合标志::e_坐标: {
			break;
		}
		case E_顶点组合标志::e_坐标_UV: {
			break;
		}
		case E_顶点组合标志::e_坐标_权重: {
			break;
		}
		case E_顶点组合标志::e_坐标_法线: {
			S_VN* xyz = f_buf_VN_ptr(*me->m_顶点);
			break;
		}
		case E_顶点组合标志::e_坐标_颜色: {
			break;
		}
	}
}



void f_surface_push顶点(S_Mesh* mesh, const std::vector<vec3>& vert) {
	switch (*mesh->m_顶点配置Flags) {
	case E_顶点组合标志::e_坐标_法线: {
		break;
	}
	case E_顶点组合标志::e_坐标_法线_UV: {
		break;
	}
	case E_顶点组合标志::e_坐标_法线_UV_颜色: {
		break;
	}
	case E_顶点组合标志::e_坐标_UV: {
		break;
	}
	case E_顶点组合标志::e_坐标_颜色: {
		std::vector<uint32> color(vert.size(), 0xffffffff);
		break;
	}
	case E_顶点组合标志::e_坐标_权重: {
		break;
	}

	case E_顶点组合标志::e_坐标:
	default: {
		f_buf_push_back(*mesh->m_顶点, vert);
		break;
	}
	}
	
	if (mesh->m_颜色) {
		std::vector<uint32> color(vert.size(), 0xffffffff);
		f_buf_push_back(mesh->m_颜色, color);
	}
}

void f_surface_push索引(S_Mesh* mesh, const std::vector<uint32>& index) {
	//f_buf_push_back(mesh->m_索引, index);
	f_buf_push_back(*mesh->m_索引, index);
}

void f_surface_fill纹理坐标索引(S_Mesh* mesh, const std::vector<uint32>& index) {
	mesh->f_fillUV索引数据(sizeof(uint32), index.size(), index.data());
	mesh->m_UV索引;
}

void f_surface_fill绘制区间(S_Mesh* mesh, const std::vector<S_VkDrawIndirectCommand>& indirect) {
	if (!mesh->m_间接) {
		//mesh->m_间接 = f_buf_create板载缓存(mesh->m_Ctx, E_板载缓存类型::e_INDIRECT, sizeof(S_VkDrawIndirectCommand));
		mesh->m_间接 = (S_GPU内存块索引*)malloc(sizeof(S_GPU内存块索引));
		*mesh->m_间接 = f_buf_alloc(S_Mesh::g_间接, indirect.size());
	}
	f_gbuf_fill(*mesh->m_间接, indirect.data(), 0, indirect.size());
	//f_buf_fill板载缓存(mesh->m_间接, indirect);
}

void f_surface_fill绘制区间(S_Mesh* mesh, const std::vector<S_VkDrawIndexedIndirectCommand>& indirect) {
	if (!mesh->m_间接) {
		//mesh->m_间接 = f_buf_create板载缓存(mesh->m_Ctx, E_板载缓存类型::e_INDIRECT, sizeof(S_VkDrawIndexedIndirectCommand));
		mesh->m_间接 = (S_GPU内存块索引*)malloc(sizeof(S_GPU内存块索引));
		*mesh->m_间接 = f_buf_alloc(S_Mesh::g_索引间接, indirect.size());
	}
	f_gbuf_fill(*mesh->m_间接, indirect.data(), 0, indirect.size());
	//f_buf_fill板载缓存(mesh->m_间接, indirect);
}

uint32 f_surface_add间接绘制(S_Mesh* mesh, const S_VkDrawIndirectCommand& indirect) {
	if (!mesh->m_间接) {
		mesh->m_间接 = (S_GPU内存块索引*)malloc(sizeof(S_GPU内存块索引));
		*mesh->m_间接 = f_buf_alloc(S_Mesh::g_间接, 0);
	}
	f_buf_push_back<S_VkDrawIndirectCommand>(*mesh->m_间接, { indirect });
	f_buf_push_back<S_MeshTranformProp>(mesh->m_网格元素属性, {MeshProp_Init()});
	return mesh->m_间接->m_Mem.m_偏移;
}
uint32 f_surface_add间接绘制(S_Mesh* mesh, const S_VkDrawIndexedIndirectCommand& indirect) {
	if (!mesh->m_间接) {
		mesh->m_间接 = (S_GPU内存块索引*)malloc(sizeof(S_GPU内存块索引));
		*mesh->m_间接 = f_buf_alloc(S_Mesh::g_索引间接, 0);
	}
	
	f_buf_push_back<S_VkDrawIndexedIndirectCommand>(*mesh->m_间接, {indirect});
	f_buf_push_back<S_MeshTranformProp>(mesh->m_网格元素属性, { MeshProp_Init() });
	return mesh->m_间接->m_Mem.m_大小;
}

void f_surface_mov绘制区间(S_Mesh* mesh, uint32 loc) {
	f_buf_erase(*mesh->m_间接, loc);
	f_buf_erase(mesh->m_网格元素属性, loc);
}

void f_surface_set间接绘制区间(S_Mesh* mesh, const S_VkDrawIndirectCommand& indirect, uint32 loc) {
	f_buf_at_Indirect(*mesh->m_间接, loc) = indirect;
}



void f_surface_fill顶点数据(S_Surface2D* mesh, const std::vector<vec2>& data) {
	f_buf_fill板载缓存(mesh->m_顶点.m_Buf, data, E_板载缓存类型::e_VBO);
}

void f_surface_fill颜色(S_Mesh* mesh, const S_RGBA8UI& color, uint32 实例S, uint32 数量) {
	if (数量 > mesh->m_颜色->m_Size - 实例S) {
		数量 = mesh->m_颜色->m_Size - 实例S;
	}

	mesh->m_颜色->f_map();
	uint32* color_p = (uint32*)(mesh->m_颜色->m_mappedPtr);

	for (uint32 i = 0; i < 数量; ++i) {
		color_p[i + 实例S] = f_PackData4X8(color);
	}

	mesh->m_颜色->f_unmap();
}

uint32 f_surface_fill顶点数据(S_Mesh* mesh, const std::vector<S_VNT1>& data) {
	*mesh->m_顶点配置Flags = E_顶点组合标志::e_坐标_法线_UV;
	return mesh->f_填充顶点数据(sizeof(S_VNT1), data.size(), (void*)data.data());
}

uint32 f_surface_fill顶点数据(S_Mesh* mesh, const std::vector<S_VN>& data) {
	*mesh->m_顶点配置Flags = E_顶点组合标志::e_坐标_法线;
	return mesh->f_填充顶点数据(sizeof(S_VN), data.size(), (void*)data.data());
}

uint32 f_surface_fill顶点数据(S_Mesh* mesh, const std::vector<S_VC>& data) {
	*mesh->m_顶点配置Flags = E_顶点组合标志::e_坐标_颜色;
	return mesh->f_填充顶点数据(sizeof(S_VC), data.size(), (void*)data.data());
}

/*void f_set顶点数据(S_Mesh* mesh, const vec3& data, uint32 offset) {
	auto* m = dynamic_cast<S_VKMesh板载缓存*>(mesh);
	f_buf_set(m->m_顶点, offset, &data);
	*mesh->m_顶点配置Flags = E_顶点组合标志::e_坐标;
}*/





void f_surface_get顶点坐标(S_Mesh* mesh, std::vector<vec3>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_大小;
	data.resize(num);

	if(!num) return;

	vec3* verts = data.data();
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);

		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vn[i].vert;
		}
	}else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vnt = (S_VNT1*)顶点.point;
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vnt[i].vert;
		}
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		memcpy(verts, v, num * sizeof(vec3));
	}
	//mesh->f_unmap顶点();
}

void f_surface_get顶点法线(S_Mesh* mesh, std::vector<vec3>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_大小;
	data.resize(num);

	if (!num) return;

	vec3* verts = data.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vn[i].normal;
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vnt[i].normal;
		}
	}
	else {
		for (uint32 i = 0; i < num; ++i){
			verts[i] = { 0,1,0 };
		}
	}
}

void f_surface_get纹理坐标(S_Mesh* mesh, std::vector<vec2>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_大小;
	data.resize(num);

	if (!num) return;

	vec2* verts = data.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vn = (S_VNT1*)顶点.point;
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vnt[i].UV;
		}
	}
}

void f_surface_get顶点数据(S_Mesh* mesh, std::vector<S_VN>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_大小;
	data.resize(num);

	if (!num) return;

	S_VN* verts = data.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		memcpy(verts, vn, num * sizeof(S_VN));
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i].vert = v[i];
			verts[i].normal = { 0,1,0 };
		}
	}
}

void f_surface_get顶点索引(S_Mesh* mesh, std::vector<uvec3>& data) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);
	uint32 num = mesh->m_索引->m_Mem.m_大小;

	data.resize(num / 3);
	if (num) {
		uvec3* index = data.data();
		memcpy((uint8*)index, (uint8*)p索引, num * sizeof(uint32));
	}
}

void f_surface_get顶点索引(S_Mesh* mesh, std::vector<uint32>& data) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);
	uint32 num = mesh->m_索引->m_Mem.m_大小;

	data.resize(num);
	if (num) {
		uint32* index = data.data();
		memcpy((uint8*)index, (uint8*)p索引, num * sizeof(uint32));
	}
}

vec3 f_surface_get顶点坐标(S_Mesh* mesh, const Mat44f& mat, uint32 id) {
	vec3 v = {};
	
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		v = mat * vn[id].vert;
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VC* vc = f_buf_VC_ptr(*mesh->m_顶点);
		v = mat * vc[id].vert;
	}
	else {
		v = mat * f_buf_Vec3_ptr(*mesh->m_顶点)[id];
	}
	return v;
}

vec3 f_surface_get全局偏移顶点坐标(S_Mesh* mesh, const Mat44f& mat, uint32 id) {
	vec3 v = {};
	auto 顶点 = mesh->m_顶点->m_Buf->m_mappedPtr;
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = (S_VN*)顶点;
		v = mat * vn[id].vert;
		
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VC* vc = (S_VC*)顶点;
		v = mat * vc[id].vert;
	}
	else {
		v = mat * ((vec3*)顶点)[id];
	}
	return v;
}





void f_surface_合并(const std::vector<S_Mesh*>& meshs, S_Mesh& mesh) {
	S_Mesh_CPU* 网格 = dynamic_cast<S_Mesh_CPU*>(&mesh);

	网格->m_positions.clear();
	网格->m_indices.clear();

	if (网格) {
		uint32 offset = 0;

		for (auto& e : meshs) {
			std::vector<vec3> 顶点;
			f_surface_get顶点坐标(e, 顶点);
			std::vector<uvec3> 索引;
			f_surface_get顶点索引(e, 索引);

			
			uint32 num = 索引.size();
			auto* p_索引 = 索引.data();
			for (uint32 i = 0; i < num; ++i) {
				p_索引[i].x += offset;
				p_索引[i].y += offset;
				p_索引[i].z += offset;
			}
			

			
			网格->m_positions.insert(网格->m_positions.begin(), 顶点.begin(), 顶点.end());
			//网格->m_indices.insert(网格->m_indices.begin(), 索引.begin(), 索引.end());

			offset = 网格->m_indices.size();
			网格->m_indices.resize(offset + num * 3);
			memcpy(&(网格->m_indices[offset]), 索引.data(), num * sizeof(uvec3));

			offset = 网格->m_positions.size();
		}
	}
	
}

void f_surface_数组合并(std::vector<S_VN>& data, const DEF_3Fs& v, const DEF_3Fs& n) {
	
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* 法线 = n.data();
	for (uint32 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = 法线[i];
	}
}

void f_surface_数组合并(std::vector<S_VC>& data, const DEF_3Fs& v, const std::vector<S_RGBA8UI>& color) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* 颜色 = color.data();
	for (uint32 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].color = f_PackData4X8(颜色[i]);
	}
}

void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_3Fs& n, const DEF_2Fs& t) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* normal = n.data();
	auto* uv = t.data();

//#pragma omp_set_num_threads(4);
#pragma omp parallel for
	for (int64 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = normal[i];
		包[i].UV = uv[i];
	}
}

void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_2Fs& t) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto * 顶点 = v.data();
	auto* uv = t.data();
	for (int64 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = {0,0,0};
		包[i].UV = uv[i];
	}
}

void f_surface_计算面中心点(S_Mesh* mesh, std::vector<vec3>& 中心点) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);

	uint32 num = mesh->m_索引->m_Mem.m_大小 / 3;
	

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);

		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			auto q = f_三角形中心坐标(vn[index.x].vert, vn[index.y].vert, vn[index.z].vert);
			中心点.push_back(q);
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vn = (S_VNT1*)顶点.point;
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);

		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			auto q = f_三角形中心坐标(vnt[index.x].vert, vnt[index.y].vert, vnt[index.z].vert);
			中心点.push_back(q);
		}
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			auto q = f_三角形中心坐标(v[index.x], v[index.y], v[index.z]);
			中心点.push_back(q);
		}
	}
}

void f_surface_计算面法线(S_Mesh* mesh, std::vector<vec3>& 法线) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);

	uint32 num = mesh->m_索引->m_Mem.m_大小 / 3;
	
	法线.resize(num);
	auto* normal_ptr = 法线.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
#pragma omp parallel for
		for (int32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			normal_ptr[i] = f_surface_从面计算法线(vn[index.x].vert, vn[index.y].vert, vn[index.z].vert);
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vn = (S_VNT1*)顶点.point;
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
#pragma omp parallel for
		for (int32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			normal_ptr[i] = f_surface_从面计算法线(vnt[index.x].vert, vnt[index.y].vert, vnt[index.z].vert);
		}
	}
	else {
		//vec3* p顶点 = (vec3*)顶点.point;
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
#pragma omp parallel for
		for (int32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			normal_ptr[i] = f_surface_从面计算法线(v[index.x], v[index.y], v[index.z]);
		}
	}
}

void f_surface_变换(S_Mesh* mesh, const S_Tranform& t) {
	//auto 顶点 = mesh->f_map顶点();
	C_Mat44 mat = f_从变换构建矩阵(t.location, t.rotation, t.scale);
	
	//uint32 num = 顶点.count;
	uint32 num = mesh->m_顶点->m_Mem.m_大小;
	//std::vector<vec3> verts(num);

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			//verts[i] = mat * vn[i].vert;
			vn[i].vert *= mat;
		}
	}
	else {
		//vec3* vn = (vec3*)顶点.point;
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			//verts[i] = mat * vn[i];
			v[i] *= mat;
		}
	}
	//mesh->f_unmap顶点();
}


#define DEF_surface_计算包围盒(_v, _num) {		\
	for (uint32 i = 0; i < _num; ++i) {			\
		最大 = vec_Max(最大, _v[i].vert);       \
		最小 = vec_Min(最小, _v[i].vert);       \
	}											\
}                                               \


//#define DEF_surface_计算包围盒_mat(_v, _num, _mat) {  \
//	for (uint32 i = 0; i < _num; ++i) {               \
//		vec3 v = (*_mat) * _v[i].vert;                \		 
//		最大 = vec_Max(最大, v);                      \
//		最小 = vec_Min(最小, v);                      \
//	}                                   	          \
//}



S_Bounding f_surface_计算包围盒(S_Mesh* mesh, const Mat44f* mat) {
	//auto* 顶点 = mesh->m_顶点->m_Buf->m_mappedPtr;
	uint32 num = mesh->m_顶点->m_Mem.m_大小;
	
	if(!num) {
		mesh->m_Bound = {};
		mesh->m_包围盒 = {};
		return {};
	}


	vec3 最小 = {};
	vec3 最大 = {};
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		if (mat) {
			//DEF_surface_计算包围盒_mat(vn, num, mat);
		}
		else {
			DEF_surface_计算包围盒(vn, num);
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VC* vn = f_buf_VC_ptr(*mesh->m_顶点);
		if (mat) {
			//DEF_surface_计算包围盒_mat(vn, num, mat);
		}
		else {
			DEF_surface_计算包围盒(vn, num);
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		S_VNT1* vn = f_buf_VNT_ptr(*mesh->m_顶点);
		if (mat) {
			//DEF_surface_计算包围盒_mat(vn, num, mat);
		}
		else {
			DEF_surface_计算包围盒(vn, num);
		}
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			最大 = vec_Max(最大, v[i]);
			最小 = vec_Min(最小, v[i]);
		}
	}

	//mesh->f_unmap顶点();

	mesh->m_Bound = { 最小 , 最大 };
	mesh->m_包围盒.size = 最大 - 最小;
	mesh->m_包围盒.pos = mesh->m_包围盒.size * 0.5 + 最小;
	return mesh->m_Bound;
}

S_Bounding f_surface_计算包围盒(S_Mesh* mesh, uint32 vertOffset, uint32 vertNum) {
	auto* 顶点 = mesh->m_顶点->m_Buf->m_mappedPtr;

	vec3 最小 = {};
	vec3 最大 = {};
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = (S_VN*)顶点;
		DEF_surface_计算包围盒(vn, vertNum);
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VC* vn = (S_VC*)顶点;
		DEF_surface_计算包围盒(vn, vertNum);
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		S_VNT1* vn = (S_VNT1*)顶点;
		DEF_surface_计算包围盒(vn, vertNum);
	}
	else {
		vec3* v = (vec3*)顶点;
		for (uint32 i = 0; i < vertNum; ++i) {
			最大 = vec_Max(最大, v[i]);
			最小 = vec_Min(最小, v[i]);
		}
	}

	mesh->m_Bound = { 最小 , 最大 };
	//mesh->m_包围盒.size = 最大 - 最小;
	//mesh->m_包围盒.pos = mesh->m_包围盒.size * 0.5 + 最小;
	return mesh->m_Bound;
}

vec3 f_surface_计算包围盒大小(S_Mesh* mesh, const Mat44f& mat) {
	S_Bounding cube = f_surface_计算包围盒(mesh, &mat);

	cube.max = mat * cube.max;
	cube.min = mat * cube.min;

	return vec_sub(cube.max, cube.min);
}



bool f_surface_射线面相交(S_Mesh* mesh, const Mat44f& mat, float32 独立缩放, const vec3& s, const vec3& dir, vec3& 交点, float32& min距离) {
	uint32 num = mesh->f_get顶点数量();
	if (!num) return false;

	bool 使用索引 = true;
	uvec3* p索引 = nullptr;
	if (!(mesh->m_索引->m_Mem.m_大小)) {
		使用索引 = false;
		num /= 3;
	}
	else {
		num = mesh->m_索引->m_Mem.m_大小 / 3;
		p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);
	}


	uint32 线程数 = 16;
	float32 最小距离 = 900000000.0f;
	vec3 最小相交坐标 = {};
	vec3 相交坐标 = {};



	bool 是否相交 = false;
	int32 相交情况 = 0;
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1, v2, v3;
			if (使用索引) {
				uvec3 index = p索引[i];
				v1 = mat * (vn[index.x].vert * 独立缩放);
				v2 = mat * (vn[index.y].vert * 独立缩放);
				v3 = mat * (vn[index.z].vert * 独立缩放);
			}
			else {
				v1 = mat * (vn[i * 3].vert * 独立缩放);
				v2 = mat * (vn[i * 3 + 1].vert * 独立缩放);
				v3 = mat * (vn[i * 3 + 2].vert * 独立缩放);
			}

			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, s));
				if (距离 < 最小距离) {
					最小距离 = 距离;
					最小相交坐标 = 相交坐标;
					是否相交 = true;
				}
			}
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vn = (S_VNT1*)顶点.point;
		S_VNT1* vn = f_buf_VNT_ptr(*mesh->m_顶点);
//#pragma omp parallel for num_threads(线程数)
		for (int32 i = 0; i < num; ++i) {
			vec3 v1, v2, v3;
			if (使用索引) {
				uvec3 index = p索引[i];
				v1 = mat * (vn[index.x].vert * 独立缩放);
				v2 = mat * (vn[index.y].vert * 独立缩放);
				v3 = mat * (vn[index.z].vert * 独立缩放);
			}
			else {
				v1 = mat * (vn[i*3      ].vert * 独立缩放);
				v2 = mat * (vn[i * 3 + 1].vert * 独立缩放);
				v3 = mat * (vn[i * 3 + 2].vert * 独立缩放);
			}
			
			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, s));
				if (距离 < 最小距离) {
					最小距离 = 距离;
					最小相交坐标 = 相交坐标;
					是否相交 = true;
				}
			}
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vn = (S_VC*)顶点.point;
		S_VC* vn = f_buf_VC_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1, v2, v3;
			if (使用索引) {
				uvec3 index = p索引[i];
				v1 = mat * (vn[index.x].vert * 独立缩放);
				v2 = mat * (vn[index.y].vert * 独立缩放);
				v3 = mat * (vn[index.z].vert * 独立缩放);
			}
			else {
				v1 = mat * (vn[i * 3].vert * 独立缩放);
				v2 = mat * (vn[i * 3 + 1].vert * 独立缩放);
				v3 = mat * (vn[i * 3 + 2].vert * 独立缩放);
			}

			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, s));
				if (距离 < 最小距离) {
					最小距离 = 距离;
					最小相交坐标 = 相交坐标;
					是否相交 = true;
				}
			}
		}
	}
	else {
		//vec3* p顶点 = (vec3*)顶点.point;
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];

			vec3 v1 = mat * (v[index.x] * 独立缩放);
			vec3 v2 = mat * (v[index.y] * 独立缩放);
			vec3 v3 = mat * (v[index.z] * 独立缩放);
			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, s));
				if (距离 < 最小距离) {
					最小距离 = 距离;
					最小相交坐标 = 相交坐标;
					是否相交 = true;
				}
			}
		}
	}

	min距离 = 最小距离;
	return 是否相交;
}




int32 f_surface_线相交(S_Mesh* mesh, const Mat44f& mat, const vec3& s, const vec3& e, float32& 距离) {
	int32 线ID = -1;

	uint32 num = mesh->f_get顶点数量() - 1;
	if (!num) return false;

	//auto 顶点 = mesh->f_map顶点();

	vec3 dir = vec_normalize2(e - s);
	//vec3 dir = (e - s);
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1 = mat * vn[i].vert;
			vec3 v2 = mat * vn[i + 1].vert;

			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir));
			if (两线段距离 < 距离) {
				距离 = 两线段距离;
				线ID = i;
			}
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vc = (S_VC*)顶点.point;
		S_VC* vc = f_buf_VC_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1 = mat * vc[i].vert;
			vec3 v2 = mat * vc[i + 1].vert;
			//v1 = vec_normalize2(v2 - v1);
			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir)); //if(!i)std::cout << "两线段距离:" << 两线段距离 << std::endl;
			if (fabs(两线段距离) < 距离) {
				距离 = 两线段距离;
				线ID = i;
			}
		}
	}
	else {
		//vec3* p顶点 = (vec3*)顶点.point;
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1 = mat * v[i];
			vec3 v2 = mat * v[i+1];

			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir));
			if (两线段距离 < 距离) {
				距离 = 两线段距离;
				线ID = i;
			}
		}
	}

	//mesh->f_unmap顶点();
	return 线ID;
}









Vec3 f_SampleSDFGrad(const float* sdf, const uvec3& dim, const ivec3& xyz)
{
	int x0 = DEF_Max(xyz.x - 1, 0);
	int x1 = DEF_Min(xyz.x + 1, dim.x - 1);

	int y0 = DEF_Max(xyz.y - 1, 0);
	int y1 = DEF_Min(xyz.y + 1, dim.y - 1);

	int z0 = DEF_Max(xyz.z - 1, 0);
	int z1 = DEF_Min(xyz.z + 1, dim.z - 1);

	float dx = (f_SampleSDF(sdf, dim, x1, xyz.y, xyz.z) - f_SampleSDF(sdf, dim, x0, xyz.y, xyz.z)) * (dim.x * 0.5f);
	float dy = (f_SampleSDF(sdf, dim, xyz.x, y1, xyz.z) - f_SampleSDF(sdf, dim, xyz.x, y0, xyz.z)) * (dim.y * 0.5f);
	float dz = (f_SampleSDF(sdf, dim, xyz.x, xyz.y, z1) - f_SampleSDF(sdf, dim, xyz.x, xyz.y, z0)) * (dim.z * 0.5f);

	return Vec3(dx, dy, dz);
}





static Inline S_Mesh* f_mesh_创建体素提取网格(const S_Mesh* srcMesh) {
	S_设备环境 ctx; ctx.m_Type = E_绘图API::E_Vulkan; ctx.m_物理设备 = {}; ctx.m_逻辑设备 = {}, E_MS次数::e_MS_1;
	S_Mesh* mesh = f_surface_创建网格对象(srcMesh, ctx, E_网格数据枚举::e_Mesh_CUDA);
	return mesh;
}


void f_fromMesh创建体素(S_体素& vo, const S_Mesh* srcMesh, vec3 移动, vec3 旋转, vec3 缩放, float 间距, float jitter) {
	if (!srcMesh || 间距 <= 0.0000001) return;

	vo.m_坐标.clear();
	vo.m_法线.clear();

	S_Mesh* mesh = f_mesh_创建体素提取网格(srcMesh);
	{
		Vec3 loc(移动.x, 移动.y, 移动.z );

		
		
		//auto 旋转矩阵 = f_构建欧拉角旋转矩阵(旋转);
		auto q = f_graph_欧拉角转四元数(旋转);
		auto 旋转矩阵 = RotationMatrix({ q.x, q.y, q.z, q.w });
		//auto 旋转矩阵 = f_mat_从四元数构建旋转矩阵(旋转.w, { 旋转.x, 旋转.y, 旋转.z });
		//mesh->f_Transform(旋转矩阵);

		Vec3 meshLower, meshUpper;
		mesh->f_getBounds(meshLower, meshUpper);

		
		//Vec3	edges = (meshUpper - meshLower) * ;
		Vec3	edges	= (meshUpper - meshLower);
		float32	maxEdge	= DEF_Max(DEF_Max(edges.x, edges.y), edges.z);
		
		
		
		// put mesh at the origin and scale to specified size
		// 归一化模型
		//Matrix44 xform = ScaleMatrix(Vec3(缩放.x, 缩放.y, 缩放.z) / maxEdge) * TranslationMatrix(Point3(-meshLower));
		//Matrix44 xform = ScaleMatrix(1.0f / maxEdge) * TranslationMatrix(Point3(-meshLower));
		//mesh->f_Transform(xform);
		// recompute expanded edges
		//edges = meshUpper - meshLower;
		//maxEdge = DEF_Max(DEF_Max(edges.x, edges.y), edges.z);
		// tweak spacing to avoid edge cases for particles laying on the boundary
		// just covers the case where an edge is a whole multiple of the spacing.
		//调整间距，以避免边缘情况下粒子位于边界上
		//仅涵盖边缘是间距的整数倍的情况。
		float 边缘间距 = 间距 * (1.0f - 1e-4f);
		//float 边缘间距 = 间距;
		auto selce = Vec3(缩放.x, 缩放.y, 缩放.z);

		// make sure to have at least one particle in each dimension
		//确保每个方向上至少有一个粒子
		int dx, dy, dz;
		dx = 间距 > edges.x ? 1 : int(edges.x / 边缘间距);
		dy = 间距 > edges.y ? 1 : int(edges.y / 边缘间距);
		dz = 间距 > edges.z ? 1 : int(edges.z / 边缘间距);

		vo.m_维度.x = dx + 4;
		vo.m_维度.y = dy + 4;
		vo.m_维度.z = dz + 4;
		//int maxDim = DEF_Max(DEF_Max(dx, dy), dz);

		// expand border by two voxels to ensure adequate sampling at edges
		//通过两个体素扩展边界以确保在边缘进行足够的采样
		meshLower -= 2.0f * Vec3(间距) + 间距;
		meshUpper += 2.0f * Vec3(间距) + 间距;
		//maxDim += 4;


		uint64 体素数量 = vo.m_维度.x * vo.m_维度.y * vo.m_维度.z;
		std::vector<uint32_t> voxels(体素数量);
		
		vo.m_Index.resize(体素数量);
		vo.m_Mask.resize(体素数量);

		// we shift the voxelization bounds so that the voxel centers
		// lie symmetrically to the center of the object. this reduces the 
		// chance of missing features, and also better aligns the particles
		// with the mesh
		Vec3 meshOffset;
		meshOffset.x = 0.5f * (间距 - (edges.x - (dx - 1) * 间距));
		meshOffset.y = 0.5f * (间距 - (edges.y - (dy - 1) * 间距));
		meshOffset.z = 0.5f * (间距 - (edges.z - (dz - 1) * 间距));
		meshLower -= meshOffset;




		//Voxelize(*mesh, dx, dy, dz, &voxels[0], meshLower - Vec3(spacing*0.05f) , meshLower + Vec3(maxDim*spacing) + Vec3(spacing*0.05f));
		std::vector<Point3>& 顶点 = *((std::vector<Point3>*)mesh->f_get顶点());
		std::vector<Vec3>& 法线 = *((std::vector<Vec3>*)mesh->f_get法线());
		std::vector<uint32>& 索引 = *((std::vector<uint32>*)mesh->f_get索引());
		Voxelize((const Vec3*)顶点.data(), 
					顶点.size(), 
					(const int32*)索引.data(), 
					索引.size(), 
					vo.m_维度.x, vo.m_维度.y, vo.m_维度.z, 
					&voxels[0], 
					meshLower ,
			meshUpper*2);
		//meshLower + Vec3(vo.m_维度.x * 间距, vo.m_维度.y * 间距, vo.m_维度.z * 间距));

		

		std::vector<float> SDF(体素数量);
		MakeSDF(&voxels[0], vo.m_维度.x, vo.m_维度.y, vo.m_维度.z, &SDF[0]);

		auto* indexs = vo.m_Index.data();
		auto* mask = vo.m_Mask.data();

		
		for (int z = 0; z < vo.m_维度.z; ++z) {
			int32 层ID = (z * vo.m_维度.x * vo.m_维度.y);

			for (int y = 0; y < vo.m_维度.y; ++y) {
				for (int x = 0; x < vo.m_维度.x; ++x) {
					const int index = 层ID + (y * vo.m_维度.x) + x;

					// if voxel is marked as occupied the add a particle
					if (voxels[index]) {
						indexs[index] = vo.m_坐标.size();

						//Vec3 position = meshLower + 间距 * 2 * Vec3(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f) + RandomUnitVector() * jitter;
						Vec3 position = meshLower + 间距*2.0f * Vec3(float(x), float(y), float(z)) + RandomUnitVector() * jitter;
						//position -= maxEdge*0.5;
						position = 旋转矩阵 * position;
						position = selce * position;
						

						position += loc - 边缘间距*2;

						vo.m_坐标.push_back(vec3{ position.x, position.y, position.z });

						Vec3 n = SafeNormalize(f_SampleSDFGrad(&SDF[0], vo.m_维度, { int32(x), int32(y), int32(z) }));
						//n *= SDF[index] * maxEdge;
						//vo.m_长度.push_back(SDF[index] * maxEdge);
						vo.m_法线.push_back({ n.x, n.y, n.z, SDF[index] * maxEdge });
						mask[index] = 1;
					}
					else {
						indexs[index] = 0xffffffff;
						mask[index] = 0;
					}
				}
			}
		}
		//mesh->f_Transform(ScaleMatrix(1.0f + skinExpand) * TranslationMatrix(Point3(-0.5f * (meshUpper + meshLower))));
		//mesh->f_Transform(TranslationMatrix(Point3(lower + 0.5f * (meshUpper + meshLower))));

	}

}

void f_fromMesh创建体素(S_域区& vo, const S_Mesh* srcMesh, vec3 移动, vec4 旋转, vec3 缩放, float 间距) {
	S_Mesh* mesh = f_mesh_创建体素提取网格(srcMesh);

	Vec3 loc(移动.x, 移动.y, 移动.z);

	mesh->f_Transform(RotationMatrix(旋转.w, Vec3(旋转.x, 旋转.y, 旋转.z)));

	Vec3 meshLower, meshUpper;
	mesh->f_getBounds(meshLower, meshUpper);

	Vec3 edges = meshUpper - meshLower;
	float32 maxEdge = DEF_Max(DEF_Max(edges.x, edges.y), edges.z);

	// 归一化模型
	Matrix44 xform = ScaleMatrix(Vec3(缩放.x, 缩放.y, 缩放.z) / maxEdge) * TranslationMatrix(Point3(-meshLower));
	mesh->f_Transform(xform);
	mesh->f_getBounds(meshLower, meshUpper);

	edges = meshUpper - meshLower;
	maxEdge = DEF_Max(DEF_Max(edges.x, edges.y), edges.z);




	float 边缘间距 = 间距 * (1.0f - 1e-4f);

	//确保每个方向上至少有一个粒子
	int dx, dy, dz;
	dx = 间距 > edges.x ? 1 : int(edges.x / 边缘间距);
	dy = 间距 > edges.y ? 1 : int(edges.y / 边缘间距);
	dz = 间距 > edges.z ? 1 : int(edges.z / 边缘间距);

	/*vo.m_维度.x = dx + 4;
	vo.m_维度.y = dy + 4;
	vo.m_维度.z = dz + 4;*/
	
	//通过两个体素扩展边界以确保在边缘进行足够的采样
	meshLower -= 2.0f * Vec3(间距);
	meshUpper += 2.0f * Vec3(间距);
	

	//uint64 体素数量 = vo.m_维度.x * vo.m_维度.y * vo.m_维度.z;
	//std::vector<uint32_t> voxels(体素数量);

	/*vo.m_Index.resize(体素数量);
	vo.m_Mask.resize(体素数量);*/

	
	Vec3 meshOffset;
	meshOffset.x = 0.5f * (间距 - (edges.x - (dx - 1) * 间距));
	meshOffset.y = 0.5f * (间距 - (edges.y - (dy - 1) * 间距));
	meshOffset.z = 0.5f * (间距 - (edges.z - (dz - 1) * 间距));
	meshLower -= meshOffset;




	//Voxelize(*mesh, dx, dy, dz, &voxels[0], meshLower - Vec3(spacing*0.05f) , meshLower + Vec3(maxDim*spacing) + Vec3(spacing*0.05f));
	std::vector<Point3>& 顶点 = *((std::vector<Point3>*)mesh->f_get顶点());
	std::vector<Vec3>& 法线 = *((std::vector<Vec3>*)mesh->f_get法线());
	std::vector<uint32>& 索引 = *((std::vector<uint32>*)mesh->f_get索引());
	f_Voxelize遮罩(
		(const Vec3*)顶点.data(),
		顶点.size(),
		索引.data(),
		索引.size(),
		vo.m_单元属性.m_分辨率.x, vo.m_单元属性.m_分辨率.y, vo.m_单元属性.m_分辨率.z,
		vo.m_Mask,
		meshLower,
		meshLower + Vec3(vo.m_单元属性.m_分辨率.x * 间距, vo.m_单元属性.m_分辨率.y * 间距, vo.m_单元属性.m_分辨率.z * 间距)
	);

	//std::vector<float> SDF(体素数量);
	//MakeSDF(&voxels[0], vo.m_分辨率.x, vo.m_分辨率.y, vo.m_分辨率.z, &SDF[0]);

}






void f_load网格(FILE* f, S_Mesh* mesh, uint32 顶点配置标志) {
	uint32 num = 0;

	std::vector<vec3> v;
	num = file_读取序列到文件(f, &v);
	std::vector<vec3> n;
	file_读取序列到文件(f, &n);
	std::vector<uint32> i;
	file_读取序列到文件(f, &i);


	switch (顶点配置标志)
	{
	case DEF_Vert预设_vn:
		{
			std::vector<S_VN> data(num);
			for (uint32 i = 0; i < num; ++i) {
				data[i].vert = v[i];
				data[i].normal = n[i];
			}

			mesh->f_填充顶点数据(data);
			f_surface_fill索引数据(mesh, i);
		}
		break;

	case DEF_Vert预设_vnu:
		break;

	default:
		mesh->f_fill顶点(v.data(), v.size());
		mesh->f_fill法线(n);
		f_surface_fill索引数据(mesh, i);
		break;
	}

	
}

void f_save网格(FILE* f, S_Mesh* obj) {
	std::vector<vec3> v;
	obj->f_get顶点((S_结构对象指针)&v);
	std::vector<vec3> n;
	obj->f_get法线((S_结构对象指针)&n);
	std::vector<uint32> i;
	obj->f_get索引((S_结构对象指针)&i);

	
	file_写入序列到文件(f, v);
	file_写入序列到文件(f, n);
	file_写入序列到文件(f, i);
	
}

S_Mesh* f_surface_create预设虚拟体() {
	S_Mesh* mesh = f_surface_创建网格对象(E_网格数据枚举::e_Mesh_VULKAN);

	DEF_3Fs v;
	DEF_3Fs n;
	DEF_2Fs uv;
	DEF_Is index;
	std::vector<S_VkDrawIndirectCommand> Indirect;

	f_graph_构建交叉轴(v, n, uv, index);
	f_surface_fill顶点数据(mesh, v);
	f_surface_fill索引数据(mesh, index);
	//f_graph_添加间接绘制(Indirect, v, index);

	f_graph_构建方向轴(v, n, uv, index);
	f_surface_fill顶点数据(mesh, v);
	f_surface_fill索引数据(mesh, index);
	//f_graph_添加间接绘制(Indirect, v, index);

	f_graph_构建线框球(v, n, uv, index, 32);
	f_surface_fill顶点数据(mesh, v);
	f_surface_fill索引数据(mesh, index);
	//f_graph_添加间接绘制(Indirect, v, index);

	return mesh;
}














//void f_填充索引数据(S_Surface2D* mesh, const std::vector<uint32>& data) {
//f_fill板载缓存(mesh->m_索引, data, E_板载缓存类型::e_INDEX);
//








/*
S_线拾取 f_surface_线段相交(S_Mesh* mesh, const Mat44f& mat, const vec3& s, const vec3& dir, float32& 距离, S_VkDrawIndexedIndirectCommand* indirect) {
	S_线拾取 拾取线 = { 距离, 100000000, -1 };

	uint32 num = mesh->f_get顶点数量() / 2;
	if (!num) return 拾取线;

	vec3 最近距离顶点 = {};
	uint32 indexOffset = 0;
	uint32 vertOffset = 0;

	if (indirect) {
		vertOffset = indirect->vertexOffset;
		indexOffset = indirect->firstIndex / 2;
		num = indirect->indexCount / 2;
	}


	//auto 顶点 = mesh->f_map顶点();
	auto 索引 = mesh->f_map索引();
	uvec2* p索引 = (uvec2*)索引.point;

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1, v2;
			if (p索引) {
				uvec2 index = p索引[i + indexOffset];
				v1 = mat * vn[index.x + vertOffset].vert;
				v2 = mat * vn[index.y + vertOffset].vert;
			}
			else {
				uint32 index = i * 2;
				v1 = mat * vn[vertOffset + index].vert;
				v2 = mat * vn[vertOffset + index + 1].vert;
			}

			vec3 相交点;
			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir, 相交点));
			if (两线段距离 < 拾取线.相交距离) {
				拾取线.相交距离 = 两线段距离;
				拾取线.线索引 = i;
				最近距离顶点 = 相交点;
			}
		}

		距离 = vec_len(最近距离顶点 - s);
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vc = (S_VC*)顶点.point;
		S_VC* vc = f_buf_VC_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1,v2;
			if (p索引) {
				uvec2 index = p索引[i + indexOffset];
				v1 = mat * vc[index.x + vertOffset].vert;
				v2 = mat * vc[index.y + vertOffset].vert;
			}
			else {
				uint32 index = i * 2;
				v1 = mat * vc[vertOffset + index].vert;
				v2 = mat * vc[vertOffset + index + 1].vert;
			}
			//v1 = vec_normalize2(v2 - v1);
			vec3 相交点;
			float32 两线段距离 = f_graph_两线段距离(v1, v2, s, dir, 相交点); //if(!i)std::cout << "两线段距离:" << 两线段距离 << std::endl;
			if (两线段距离 >= 0 && 两线段距离 < 拾取线.相交距离) {
				拾取线.相交距离 = 两线段距离;
				拾取线.线索引 = i;
				最近距离顶点 = 相交点;
			}
		}

		距离 = vec_len(最近距离顶点 - s);
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		//vec3* p顶点 = (vec3*)顶点.point;
		for (uint32 i = 0; i < num; ++i) {
			uvec2 index;
			if (p索引) {
				index = p索引[i + indexOffset];
			}
			else {
				index.x = i * 2;
				index.y = i * 2 + 1;
			}
			vec3 v1 = mat * v[index.x + vertOffset];
			vec3 v2 = mat * v[index.y + vertOffset];


			vec3 相交点;
			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir, 相交点));
			if (两线段距离 < 拾取线.相交距离) {
				拾取线.相交距离 = 两线段距离;
				拾取线.线索引 = i;
				最近距离顶点 = 相交点;
			}

		}

		距离 = vec_len(最近距离顶点 - s);
	}


	//mesh->f_unmap顶点();
	mesh->f_unmap索引();
	return 拾取线;
}

*/